<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<meta name="referrer" content="no-referrer" />
	<!--<meta name="referrer" content="never">-->
	<title>播放</title>
	<script src="/js/Util.js"></script>
	<script src="/frame/js/broadcast.js"></script>
	<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
	<script src="https://cdn.bootcss.com/eruda/1.5.4/eruda.min.js"></script>
	<link href="https://unpkg.com/video.js@7.20.3/dist/video-js.css" rel="stylesheet">
</head>
<style>
	*{
		padding: 0;
		margin: 0;
		background-color: rgba(20,20,22);
	}
	#mask *{
		background-color: transparent;
	}
	.loadingEight{
		width: 80px;
		height: 80px;
		border-radius: 50%;
		margin: 0 auto;
		position: relative;
		border:5px solid #b7f;
		-webkit-animation: turn 2s linear infinite;
	}
	.loadingEight span{
		display: inline-block;
		width: 30px;
		height: 30px;
		border-radius: 50%;
		background: #b7f;
		position: absolute;
		left: 50%;
		margin-top: -15px;
		margin-left: -15px;
		background-color: transparent;
		-webkit-animation: changeBgColor 2s linear infinite;
	}
	@-webkit-keyframes changeBgColor{
		0%{
			background: #b7f;
		}
		50%{
			background: #83f;
		}
		100%{
			background: #b7f;
		}
	}
	@-webkit-keyframes turn{
		0%{
			-webkit-transform: rotate(0deg);
			border-color: #b7f;
		}
		50%{
			-webkit-transform: rotate(180deg);
			border-color: #83f;
		}
		100%{
			-webkit-transform: rotate(360deg);
			border-color: #b7f;
		}
	}
	.video-js{
		display: contents;
	}
	.video-js .vjs-duration{
		display: block;
	}
	.video-js .vjs-current-time{
		display: block;
	}
</style>

<script>
	eruda.init();
	var $videojsTools = {};
</script>
<script src="/js/video.js"></script>
<script src="/js/wrapper.js"></script>
<!--<script src="https://unpkg.com/video.js@7.20.3/dist/video.js"></script>-->
<script src="/js/videojs_zh_CN.js"></script>
<script src="/js/flv.min.js"></script>
<script src="/js/timer.js"></script>
<body>
<div id="mask" style="color:white;position: fixed;top: 0; bottom: 0; left: 0;right: 0; z-index: 1;background-color: rgba(0,0,0,.5);    justify-content: center;
    align-items: center;">
	<div>
		<div class="loadingEight">
			<span></span>
		</div>
		<div style="margin-top:.5em;">解析中，请稍后</div>
	</div>
</div>
<video id="video" width="100%" autoplay controls poster="//www.toopic.cn/public/uploads/small/163420460946416342046098.jpg">
	<p class="vjs-no-js">
		To view this video please enable JavaScript, and consider upgrading to a
		web browser that
		<a href="https://videojs.com/html5-video-support/" target="_blank">
			supports HTML5 video
		</a>
	</p>
</video>
</body>
<script type="text/javascript">
	var param = util.getParameter();
	var channelId = param.get("channelId");

	var broadcastChannel = new HalfDuplexBroadcast(channelId);
	var handler = new Handler("objectProxy", broadcastChannel);
	var proxyHandler = new ObjectProxyHandler(handler);
	// 仅在此处定义，初始化在下面

	var parentPageProxy = new ObjectProxy("pvideo", proxyHandler);
	parentPageProxy.addMethod("end", "reload", "pause", "play");
	parentPageProxy.addProperty("isShareRoom");

	var parserProxy = new ObjectProxy("pparser", proxyHandler);
	parserProxy.addMethod("update");

	var video = document.getElementById("video");
	var __data__ = [( ${data} )];
	var playConfig = {
		videoSeg: util.getDefault(__data__.videoSeg, {beginSeg: 0, beginSegLen: 0,endSeg: 0, endSegLen: 0}),
		time: util.getDefault(__data__.currentTime, 0, true),
		key: __data__.key,
		upload: util.getDefault(__data__.currentTime, -1) >= 0,
		url: "",
		preloaded: 5400,
		type: "mp4"
	};
	proxyHandler.binding("video", new ObjectProxyBinding({
		pause: ()=> {
			document.querySelector("video").pause();
		},
		play: ()=> {
			document.querySelector("video").play();
		},
		videoInfo: () => {
			var video = document.querySelector("video");
			return {
				type: playConfig.type,
				parser: playConfig.name,
				orign: playConfig.key,
				size: (video.videoWidth==0 || video.videoHeight==0)?-1: (video.videoWidth + " x " + video.videoHeight),
				duration: video.duration
			}
		}
	}));

	function isFullscreen(){
		return document.fullscreenElement || document.msFullscreenElement  ||
				document.mozFullScreenElement || document.webkitFullscreenElement || false;
	}

	var key = playConfig.key;
	var time = playConfig.time;

	video.height = window.innerHeight - 5;
	video.addEventListener("play", () => {
		parentPageProxy.play();
	})
	video.addEventListener("pause", () => {
		parentPageProxy.pause();
	})
	video.addEventListener("ended", function(){
		// 如果全屏，则退出全屏
		if (isFullscreen()){
			document.exitFullscreen();
		}
		uploadTime(key, -1);
		util.removeItem(key);
		parentPageProxy.end();
	});
	// 跳过片头或者片尾
	function skipSeg(start, len){
		let timer = new Timer(1000);
		timer.setEvent(function(){
			if (video.currentTime > start + len - 1){
				return false;
			}
			if (video.currentTime >= start && video.currentTime < start + len - 1){
				video.currentTime = start + len;
			}
			return true;
		})
		timer.start();
	}
	function readyPlay(){
		startRecover();
		skipSeg(playConfig.videoSeg.beginSeg, playConfig.videoSeg.beginSegLen);
		let endBegin = video.duration - playConfig.videoSeg.endSeg - playConfig.videoSeg.endSegLen;
		skipSeg(endBegin, playConfig.videoSeg.endSegLen);
	}
	async function startRecover() {
		// 如果是放映室直接返回，不记录进度数据
		if ( await parentPageProxy.isShareRoom ) {
			return;
		}
		let preUploadTime = 0;
		// upload == false 未登录使用本地数据
		if (!playConfig.upload) {
			time = util.getDefault(util.getItem(key), 0);
		}
		if (time < 0) {
			time = 0;
		}
		console.log("recover " + key + "-->" + util.getItem(key) + "-->" + time);
		video.currentTime = time;
		let timer = new Timer(5000);
		timer.setEvent(function () {
			if (video.duration > 0) {
				if (video.currentTime < video.duration - 30) {
					util.setItem(key, video.currentTime);
					if (Math.abs(video.currentTime - preUploadTime) > 60) {
						preUploadTime = video.currentTime;
						uploadTime(key, preUploadTime);
					}
				}
			}
			return true;
		});
		timer.start();
	}
	function uploadTime(key, time){
		if (!playConfig.upload){return;}
		$.post("/user/progress", {url:key,time: parseInt(time)}, function(result){
			if (result.code != 0){
				playConfig.upload = false;
				alert(result.msg);
			}
		});
	}

	function loadVideo(){
		function nextSegmentsInterval(buffEnd, nextTime, video){
			let time = new Timer(1000);
			time.setEvent(function(){
				if (video.currentTime > buffEnd - 1){
					video.currentTime = nextTime;
					return false;
				}
				return true;
			})
			time.start();
		}
		let videoType = playConfig.type;
		let preloaded = playConfig.preloaded;
		if (videoType == "hls" || videoType == "m3u8"){
			$(video).addClass("video-js vjs-default-skin vjs-big-play-centered vjs-16-9");
			videojs.hook('beforeerror', (player, err) => {
				console.log('hook - beforeerror')
				console.log(err);
				// Video.js 在切换/指定 source 后立即会触发一个 err=null 的错误，这里过滤一下
				if (err == null){
					return null;
				}
				if (err.code !== 3){
					return err;
				}
				let media = player.tech().hls.playlists.media();
				// 有效列表
				if (!(media && media.segments)){
					return err;
				}
				let playList = media.segments;
				// 已缓冲的时间位置
				let buffEnd = video.currentTime;
				if (video.buffered.length > 0){
					buffEnd = video.buffered.end(0);
				}
				// 获取下一个时间片的开始位置
				let time = 0;
				for (var i = 0, l = playList.length; i < l; i ++){
					time = time + playList[i].duration;
					if (time > buffEnd + 1){
						console.log("第" + (i-1) + "个ts,url=" + playList[i-1].uri +"加载失败");
						break;
					}
				}
				console.log(time + "  " + buffEnd + "  " + video.currentTime);
				// 从下一个时间片的1秒位置开始
				nextSegmentsInterval(buffEnd, time+1, video);
				// 清除错误，避免 error 事件在控制台抛出错误
				return null
			});
			var hlsPlayer = videojs(video, {
				bigPlayButton: false, // 显示播放按钮
				textTrackDisplay: false,
				posterImage: true,
				language: 'zh-CN',
				autoplay: true,
				preloaded: preloaded,
				errorDisplay: false,
				controlBar: {
					children: [
						{name: 'playToggle'}, // 播放按钮
						{name: 'currentTimeDisplay'}, // 当前已播放时间
						{name: 'progressControl'}, // 播放进度条
						{name: 'durationDisplay'}, // 总时间
						{ // 倍数播放
							name: 'playbackRateMenuButton',
							'playbackRates': [0.5, 1, 1.5, 2, 2.5]
						},
						{
							name: 'volumePanel', // 音量控制
							inline: false, // 不使用水平方式
						},
						{name: 'FullscreenToggle'} // 全屏
					]
				}, // 显示控件
				fluid: true,
				sources: [{
					type: "application/x-mpegURL",
					src: playConfig.url,
					poster: "//www.toopic.cn/public/uploads/small/163420460946416342046098.jpg"
				}]
			},
			function(){
				this.on('loadedmetadata',function(){
					console.log('loadedmetadata');
					readyPlay();
					hlsPlayer.play();
				});
				// 监听错误事件(如果其中一个ts文件获取失败，需要进行重试次数限制，并且重新加载视频流，以保证视频能够继续播放)
				this.tech_.on('retryplaylist', (a,b,c) => {
					console.log("ts文件获取失败404.....");
					if (video.buffered.length > 0){
						if (!video.paused && Math.ceil(video.currentTime) >= parseInt(video.buffered.end(0))){
							this.pause();
						}
					}
				})
				this.on('error',function(){
					console.log(this.error());
				})
			});
		}
		else if (videoType=="flv" || videoType=="mp4"){
			if (flvjs.isSupported()) {
				var flvPlayer = flvjs.createPlayer({
					type: videoType,
					url: playConfig.url
				});
				flvPlayer.attachMediaElement(video);
				flvPlayer.load(); //加载
				readyPlay();
			}
		}
		else if (videoType=="page"){
			util.redirect(playConfig.url);
		}
		else{
			alert("暂不支持，请截图发送管理员添加支持"+videoType);
		}
	}

	var parser = util.getDefault(param.get("parser"), "");
	var platform = util.getDefault(param.get("platform"), "");

	$.ajax({
		async: true,
		data: {data: btoa(decodeURIComponent(param.get("url"))), name: parser, platform: platform},
		type: "POST",
		url:"/api/url",
		beforeSend: () => $("#mask").css("display", "flex"),
		complete: () => $("#mask").css("display", "none"),
		success: function(result){
			console.log(result);
			parserProxy.update((result && result.code == 0) ? result.data.name: null ,parser);
			if (result && result.code == 0){
				var data = result.data;
				data.url = decodeURIComponent(data.url);
				playConfig = util.merge(playConfig, data);
				loadVideo();
			}
			else{
				document.write(result);
			}
		},
		error: () => alert("服务器错误")
	})
</script>
</html>